#include "LogicSystem.h"
#include "StatusGrpcClient.h"
#include "CSession.h"
#include "MysqlManager.h"

#include <json/reader.h>
#include <json/value.h>
#include <json/json.h>

#include <iostream>

LogicSystem::LogicSystem() : m_b_stop(false) 
{
	registerCallbacks();
	m_worker_thread = std::thread(&LogicSystem::dealMsg, this);
}

void LogicSystem::dealMsg()
{
	for (;;)
	{
		std::unique_lock<std::mutex> lock(m_mtex);
		// 判断任务队列为空并且未处于关闭状态，则用条件遍历进行阻塞等待
		while (m_msg_que.empty() && !m_b_stop) {
			m_cond.wait(lock);
		}

		// 判断是否关闭状态，如果为关闭状态，则执行完所有逻辑之后就退出循环
		if (m_b_stop) {
			// 清空队列
			while (!m_msg_que.empty()) {
				processMessage(m_msg_que.front());
			}
			break;
		}
		
		// 如果未处于关闭状态
		if (!m_msg_que.empty()) {
			processMessage(m_msg_que.front());
		}
	}
}

void LogicSystem::processMessage(std::shared_ptr<LogicNode> msg_node)
{
	std::cout << "recv_msg id is " << msg_node->m_recvnode->m_msg_id << std::endl;
	auto it_call_back = m_fun_callbacks_map.find(msg_node->m_recvnode->m_msg_id);
	if (it_call_back != m_fun_callbacks_map.end()) {
		// 进行回调
		it_call_back->second(msg_node->m_session, msg_node->m_recvnode->m_msg_id,
			std::string(msg_node->m_recvnode->m_data, msg_node->m_recvnode->m_cur_len)
		);
	}
	else {
		std::cout << "msg id [" << msg_node->m_recvnode->m_msg_id << "] handler not found" << std::endl;
	}

	// 处理完消息后从队列中移除
	m_msg_que.pop();
}


LogicSystem::~LogicSystem()
{
	m_b_stop = true;
	m_cond.notify_one();
	m_worker_thread.join();
}

void LogicSystem::postMsgToQue(std::shared_ptr<LogicNode> msg)
{
	std::unique_lock<std::mutex> lock(m_mtex);
	m_msg_que.push(msg);
	if (m_msg_que.size() > MAX_SENDQUE) {
		std::cout << "session: " << msg->m_session->getUuid() << " send que fulled, size is " << MAX_SENDQUE << std::endl;
		return;
	}

	// 任务队列有0变为1，则发送通知信号
	if (m_msg_que.size() == 1) {
		lock.unlock();
		m_cond.notify_one();
	}
}

void LogicSystem::registerCallbacks()
{
	m_fun_callbacks_map[MSG_CHAT_LOGIN] = std::bind(&LogicSystem::loginHandler, this, 
		std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
}

void LogicSystem::loginHandler(std::shared_ptr<CSession> session, const short& msg_id, const std::string& msg_data)
{
	// 解析登录的json消息
	Json::Reader reader;
	Json::Value root;
	reader.parse(msg_data, root);
	auto uid = root["uid"].asInt();
	auto token = root["token"].asString();
	std::cout << "user login is " << uid << std::endl;
	std::cout << "user token is " << token << std::endl;

	// 从StatusServer获取token并验证是否匹配
	auto rsp = StatusGrpcClient::getInstance()->login(uid, token);
	
	Json::Value ret_value;
	Defer defer([this, &ret_value, session]() {
		std::string return_str = ret_value.toStyledString();
		// 给客户端回包
		session->Send(return_str, MSG_CHAT_LOGIN_RSP);
	});

	ret_value["error"] = rsp.error();
	if (rsp.error() != ErrorCodes::Success) {
		return;
	}
	
	// 查询用户信息
	auto it = m_users.find(uid);
	std::shared_ptr<UserInfo> user_info = nullptr;
	if (it == m_users.end()) {
		// 查询Mysql数据库
		user_info = MysqlManager::getInstance()->getUserInfo(uid);
		if (user_info == nullptr) {
			ret_value["error"] = ErrorCodes::UidInvalid;
			return;
		}
		m_users[uid] = user_info;
	}
	else {
		user_info = it->second;
	}

	ret_value["uid"] = uid;
	ret_value["token"] = rsp.token();
	ret_value["name"] = user_info->name;
}
